using System;
using System.Collections.Generic;
using System.Data;

namespace Mite
{
	public interface ISqlQueryFactory
	{
		string CreateIndex(Index index);

		string DropIndex(Index index);

		string CreateTable(Table table);

		string DropTable(Table table);

		string RenameTable(Table table, string newName);

		string RenameColumn(Column column, string newName);

		/// <summary>
		/// Alter <paramref name="column"/> to match <paramref name="newColumn"/>.
		/// Renaming the column is not allowed.
		/// </summary>
		/// <param name="column">Column to alter.</param>
		/// <param name="newColumn">New column definition.</param>
		/// <exception cref="InvalidOperationException"><paramref name="column"/> and <paramref name="newColumn"/> must have the same name.</exception>"
		string AlterColumn(Column column, Column newColumn);

		/// <summary>
		/// Add <paramref name="column"/> to <paramref name="table"/>.
		/// </summary>
		/// <param name="table"><see cref="Table"/> to which to add <paramref name="column"/>.</param>
		/// <param name="column"><see cref="Column"/> to add.</param>
		/// <returns><see cref="IDbCommand"/> to add <paramref name="column"/> to <paramref name="table"/>.</returns>
		/// <exception cref="InvalidOperationException">Table already contains column.</exception>
		string AddColumnToTable(Table table, Column column);

		/// <summary>
		/// Generate sql to drop <paramref name="columns"/>.
		/// Columns must all be associated with the same <see cref="Table"/>.
		/// </summary>
		/// <param name="table">Table to which the columns belong.</param>
		/// <param name="columns">Column to drop.</param>
		/// <exception cref="ArgumentNullException"><paramref name="columns"/> can not be <c>null</c>.</exception>
		/// <exception cref="ArgumentException"><paramref name="columns"/> can not be empty.</exception>
		string DropColumns(string table, params string[] columns);

		/// <summary>
		/// Generate sql to add a foreign key.
		/// </summary>
		/// <param name="table">Table for the constraint.</param>
		/// <param name="referenceTable">Reference table for the constraint.</param>
		/// <param name="name">Name of the foreign key constraint.</param>
		/// <param name="referenceMap">Key value pairs associating a column in the table to a column in the reference table.</param>
		string AddForeignKey(string table, string referenceTable, string name, params KeyValuePair<string, string>[] referenceMap);

		/// <summary>
		/// Generate sql to drop constraint.
		/// </summary>
		string DropConstraint(string table, string name);
	}
}